package com.example.demo.cron;

import com.example.demo.config.ScheduleConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;

import java.util.concurrent.ScheduledFuture;

@Slf4j
@Component
public class DynamicTimedTask {

    private volatile boolean isRunning = false;

    private ScheduledFuture<?> future;

    private ThreadPoolTaskScheduler threadPoolTaskScheduler;

    @Autowired
    public void setThreadPoolTaskScheduler(ThreadPoolTaskScheduler threadPoolTaskScheduler) {
        this.threadPoolTaskScheduler = threadPoolTaskScheduler;
    }

    public void start(Runnable runnable, String cron) {
        stop();
        future = threadPoolTaskScheduler.schedule(runnable, new CronTrigger(cron));
    }

    public void stop() {
        if (isRunning) {
            future.cancel(true);
        }
    }

    public void startCron(Runnable runnable, String name, String cron) {
        ScheduledFuture scheduledFuture = threadPoolTaskScheduler.schedule(runnable, new CronTrigger(cron));
        ScheduleConfig.cache.put(name, scheduledFuture);
    }

    public void stop(String taskName) {
        if (ScheduleConfig.cache.isEmpty()) return;
        if (ScheduleConfig.cache.get(taskName) == null) return;

        ScheduledFuture scheduledFuture = ScheduleConfig.cache.get(taskName);

        if (scheduledFuture != null) {
            scheduledFuture.cancel(true);   // 这里需要使用指定的 scheduledFuture 来停止当前的线程
            ScheduleConfig.cache.remove(taskName);        // 移除缓存
        }
    }

    public void stopAll(){
        if (ScheduleConfig.cache.isEmpty()) return;
        ScheduleConfig.cache.values().forEach(scheduledFuture -> scheduledFuture.cancel(true) );
    }

    public class InnerTask implements Runnable {

        private final Runnable runnable;

        public InnerTask(Runnable runnable) {
            this.runnable = runnable;
        }

        @Override
        public void run() {
            isRunning = true;
            runnable.run();
        }
    }

}